<?php

namespace App\Services;

use App\Exceptions\ApiException;
use App\Models\Classify;
use App\Models\ProjectClassify;
use Illuminate\Database\Eloquent\Model;
use PHPUnit\Util\Exception;

/**
 * 分类目录服务层
 * Class ClassifyService
 * @package App\Services
 */
class ClassifyService extends BaseService
{
    public $approvalService;

    public function __construct(ApprovalService $approvalService)
    {
        parent::__construct();
        $this->approvalService = $approvalService;
    }

    /**
     * 添加一个分类目录
     */
    public function saveData($id, $params)
    {
        if ($id) {
            $classify = Classify::query()->find($id);
            CommonService::addActionLog('更新一个分类目录', "数据ID:{$id}");
        } else {
            $classify = new Classify();
            CommonService::addActionLog('添加一个分类目录', "数据ID:{$classify->id}");
        }
        $classify->project_no       = $params['project_no'];
        $classify->template_id      = $params['template_id'];
        $classify->parent_id        = $params['parent_id'];
        $classify->title            = $params['title'];
        $classify->archives_no      = $params['archives_no'] ?: ''; //档案号
        $classify->stage_code       = $params['stage_code'] ?: ''; //阶段代码
        $classify->type             = $params['type']; //种类J和K
        $classify->major_code       = $params['major_code'] ?: ''; //专业代码
        $classify->early_stage_code = $params['early_stage_code'] ?: ''; //早期阶段代码
        $classify->creator_id       = user_id();
        //$classify->add_direct  = to_int($params['add_direct']); // add_direct   0不可直接添加，1可以

        return $classify->save();
    }

    /**
     * 获取数据列表
     */
    public function getList($request, $perPage): array
    {
        $thisQuery = Classify::query();

        if ($request->filled('keyword')) {
            $keyword = $request->input('keyword');
            $thisQuery->where('id', '=', $keyword)->orWhere('title', 'like', "%{$keyword}%");
        }
        $list = $thisQuery->paginate($perPage);

        if ($list->isEmpty()) return [];

        return $this->removeNoUsedPageParams($list->toArray());
    }

    /**
     * 获取一条数据信息
     */
    public function detail($id)
    {
        return Classify::query()->where('id', $id)->first()->toArray();
    }

    /**
     * 回收站列表
     */
    public function classifyRecycle($request): array
    {
        $thisQuery = Classify::onlyTrashed(); //只获取软删除的数据

        if ($request->filled('keyword')) { //判断参数是否存在并且不为空
            $keyword = $request->input('keyword');
            $thisQuery->where('title', 'like', "%{$keyword}%"); //由于不同的表字段不同，所以单独拿出来
        }

        return $this->formatRecycleData($request, $thisQuery);
    }

    /**
     * 带树状图的分类目录
     * @param int $templateId
     * @return array
     * @author: lxk
     * @date: 2024/1/31 9:20
     */
    public function treeClassifies(int $templateId): array
    {
        $allClassifies = Classify::query()->where('template_id', $templateId)->get();//获取全部分类
        if ($allClassifies->isEmpty()) return [];
        $allClassifies      = $allClassifies->toArray();
        $classifyIds        = array_column($allClassifies, 'id'); //获取全部分类的 ids
        $selectedClassifies = ProjectClassify::query()->whereIn('classify_id', $classifyIds)->get(); //参建单位设置过的分类目录
        $selectedClassifies = $selectedClassifies->isNotEmpty() ? $selectedClassifies->toArray() : [];
        $firstArr           = [
            'id'          => -1,
            'parent_id'   => 0,
            'template_id' => 8,
            'title'       => '追加的一个元素，调样式用',
            'disabled'    => true,
        ];
        array_unshift($allClassifies, $firstArr);
        foreach ($allClassifies as &$classify) {
            $classify['set_build']        = 0;
            $classify['set_supervisor']   = 0;
            $classify['set_construction'] = 0;
            $classify['is_show_action']   = 0;
            foreach ($selectedClassifies as $selected) {
                if ($classify['id'] == $selected['classify_id']) { //将选择过的分类进行标记
                    $companyType = $selected['part_company_type'];
                    if ($companyType == 1) {
                        $classify['set_build'] = 1; //建设单位
                    }
                    if ($companyType == 2) { //监理单位
                        $classify['set_supervisor'] = 1;
                    }
                    if ($companyType == 3) { //施工单位
                        $classify['set_construction'] = 1;
                    }
                }
            }
        }
        return get_tree($allClassifies);
    }

    /**
     * 分类里设置参建单位类型 其实是复制一份出来到 projectClassify
     *
     * @param $templateId
     * @param $companyType
     * @param $classifyIds
     * @return bool
     * @throws ApiException
     * @author: lxk
     * @date: 2023-03-18 9:50
     */
    public function setPartCompanyType($templateId, $companyType, $classifyIds) : bool
    {
        $classifyIds = to_array($classifyIds);
        $notAllowIds = ProjectClassify::query() //能查询出来的分类目录，不允许再添加
        ->whereIn('classify_id', $classifyIds)
            ->where('part_company_type', $companyType)
            ->pluck('classify_id');

        if ($notAllowIds->isNotEmpty()) { //不允许写入的模板分类
            $notAllowIds = $notAllowIds->toArray();
            $notAllowIds = array_unique($notAllowIds);
        } else {
            $notAllowIds = [];
        }
        $allowIds = array_diff($classifyIds, $notAllowIds); //用户选择的ids减去不需要再写入的ids

        if (empty($allowIds)) throw new ApiException('已匹配！不再重复匹配~');

        $classifyList = Classify::query()->whereIn('id', $allowIds)->get()->toArray();

        $projectClassifies = []; //定义需要批量写入的空数组
        foreach ($classifyList as $classify) {
            $projectClassify['part_company_type'] = $companyType;
            $projectClassify['template_id']       = $templateId;
            $projectClassify['title']             = $classify['title'];
            $projectClassify['classify_id']       = $classify['id'];
            $projectClassify['parent_id']         = $classify['parent_id'];
            $projectClassify['archives_no']       = $classify['archives_no'];
            $projectClassify['type']              = $classify['type']; //种类
            $projectClassify['project_no']        = $classify['project_no']; //项目代码
            $projectClassify['stage_code']        = $classify['stage_code']; //阶段代码
            $projectClassify['major_code']        = $classify['major_code'];
            $projectClassify['add_direct']        = to_int($classify['add_direct']); //0不可直接添加，1可以
            $projectClassify['is_can_edit']       = 0; //0不可以，1可以编辑
            $projectClassify['creator_id']        = user_id();
            $projectClassify['created_at']        = now();
            $projectClassify['updated_at']        = now();

            $projectClassifies[] = $projectClassify;
        }
        if (empty($projectClassifies)) {
            throw new ApiException('选择的分类已经添加到单位~');
        }
        if (!ProjectClassify::query()->insert($projectClassifies)) {
            throw new ApiException('写入失败！');
        }
        return true;
    }

    /**
     * 分类目录设置或取消单个参建单位
     * @param $classifyId //选择的模板分类ids
     * @param $companyType //匹配公司的类型 1建设 2监理 3施工
     * @param $status //1匹配, 2解除匹配
     */
    public function partCompanyStatus($templateId, $classifyId, $companyType, $status): array
    {
        try {
            if (!in_array($status, [1, 2]) || !in_array($companyType, [1, 2, 3])) {
                throw new Exception('参数错误！');
            }
            if ($status == 1) {
                $this->setPartCompanyType($templateId, $companyType, [$classifyId]);
            } else { //消单个参建单位
                ProjectClassify::query()
                    ->where('template_id', $templateId)
                    ->where('classify_id', $classifyId)
                    ->where('part_company_type', $companyType)
                    ->update(['deleted_at' => now()]);
            }
            CommonService::addActionLog('分类目录设置或取消单个参建单位');
            return ['msg' => ''];
        } catch (Exception $exception) {
            return ['msg' => $exception->getMessage()];
        }
    }

    /**
     * 根据当前用户的审核级别显示 approval_level的值等于几，
     * 就向对应审核级别的用户展示【待审批】
     * 获取待审核的分类列表
     */
    public function getNotAuditClassifies($request, $perPage)
    {
        $keyword = $request->input('keyword'); //申请人或申请内容
        $date    = $request->input('date'); //申请日期
        $status  = $request->input('status', 0); //状态
        $type    = $request->input('type', 0); //类型

        // 获取当前登录用户的审批等级
        $level = $this->approvalService->getUserApprovalLevel($type);
        if (!$level) { //如果没有配置审批等级，看不到内容
            return [];
        }
        //如果有，让用户看到匹配自身审核等级的数据
        $list = Classify::query()
            ->leftJoin('users as u', 'u.id', '=', 'classifies.creator_id')
            ->where('approval_level', $level)
            ->when($keyword, function ($query, $keyword) { //如果有关键字查询
                $search = "%{$keyword}%";
                return $query->where('u.nickname', 'like', $search)
                    ->orWhere('classifies.title', 'like', $search)
                    ->orWhere('classifies.archives_no', 'like', $search);
            })
            ->when($date, function ($query, $date) { //如果有日期查询
                return $query->whereDate('classifies.created_at', $date);
            })
            ->when($status, function ($query, $status) { //如果有状态查询
                return $query->where('classifies.status', $status);
            })
            ->select('classifies.*', 'u.id', 'u.nickname')
            ->paginate(20);

        if ($list->isEmpty()) return []; //数据为空，直接返回

        $list = $list->toArray();
        foreach ($list['data'] as &$val) { //格式化部分显示内容
            $val['nickname'] = $val['nickname'] ?: '未知'; //申请人
            $val['content']  = $val['title'] . ' ' . $val['archives_no']; //内容
            //展示分类的上级
            $parentTitle        = Classify::query()->where('id', $val['parent_id'])->value('title');
            $val['parent_text'] = !empty($val['parent_id']) ? $parentTitle : '这是一级分类';
        }

        return $list;
    }


}
